Skip to content

feat: optimize bundle by replacing react-syntax-highlighter with pris…#5599

Open
patilpratik1905 wants to merge 9 commits into
asyncapi:masterfrom
patilpratik1905:enh/perf_acc_improvement
Open

feat: optimize bundle by replacing react-syntax-highlighter with pris…#5599
patilpratik1905 wants to merge 9 commits into
asyncapi:masterfrom
patilpratik1905:enh/perf_acc_improvement

Conversation

@patilpratik1905

@patilpratik1905 patilpratik1905 commented Jun 26, 2026

Copy link
Copy Markdown

Summary of Previous Work

This PR is the result of a broader investigation into improving the website's Lighthouse performance and reducing the client-side bundle size.

The investigation started with understanding Lighthouse metrics, studying the optimization opportunities suggested by Lighthouse, and manually auditing the major pages across the website. Since Lighthouse analyzes one page at a time, each important route had to be evaluated individually to identify page-specific bottlenecks.

During this process, several optimizations were implemented, including:

  • Serving fonts and CSS locally instead of external CDNs.
  • Converting suitable images to WebP.
  • Introducing lazy loading and preloading where appropriate.
  • Continuously analyzing production bundle sizes after every optimization to measure their impact.

One challenge throughout this work was obtaining reliable performance measurements, as Lighthouse scores varied significantly between Chrome DevTools and PageSpeed Insights, making it difficult to accurately evaluate the effectiveness of each change.

Although these improvements helped, they did not produce the significant performance gains that were expected. To better understand the remaining bottlenecks, I repeatedly analyzed the production bundle before and after each optimization.

Bundle Analysis

Before

image

After

image

This deeper investigation revealed that the primary bottleneck was not the usual frontend assets, but a large syntax-highlighting runtime.

The bundle analyzer consistently showed a large highlight.js/lib chunk. After tracing its dependency chain, I discovered that while most of the project had already migrated to prism-react-renderer, the Schyma package still internally depended on react-syntax-highlighter, which itself relied on the refractor engine. Since refractor bundles hundreds of language grammars, it introduced a considerable amount of unnecessary JavaScript into the client bundle, even though Schyma only highlights JSON.

I explored replacing Schyma's syntax-highlighting implementation directly, but those approaches introduced regressions and visual inconsistencies, particularly on the schema explorer pages:

  • /docs/reference/specification/v3.0.0-explorer
  • /docs/reference/specification/v3.1.0-explorer

Therefore, the objective became finding a solution that could eliminate the unnecessary runtime without modifying Schyma itself or affecting the existing user experience.

Solution

This PR eliminates the duplicate syntax-highlighting runtime introduced by Schyma by replacing its internal react-syntax-highlighter dependency with a lightweight compatibility shim backed by the project's existing prism-react-renderer.

Using webpack aliasing, Schyma's imports are transparently redirected to the shim at build time, requiring no changes to Schyma or any of its consumers. The shim exposes the same API that Schyma expects while internally delegating rendering to prism-react-renderer, allowing Schyma to function exactly as before.

This approach:

  • Eliminates the duplicate syntax-highlighting implementation.
  • Removes the heavy react-syntax-highlighter/refractor runtime from the client bundle.
  • Preserves the existing UI, explorer functionality, and visual behavior.
  • Avoids maintaining a fork or patch of the upstream Schyma package.
  • Reuses the syntax-highlighting library already adopted across the rest of the website.

Improvements / Impact :

The performance improvements achieved in this PR primarily come from two major changes:

  1. Replaced react-syntax-highlighter with prism-react-renderer

    • Migrated the application's syntax highlighting to the lighter prism-react-renderer, reducing the overall syntax-highlighting footprint while preserving the existing rendering and appearance.
  2. Eliminated Schyma's duplicate syntax-highlighting runtime

    • Kept Schyma completely unchanged, but introduced a lightweight compatibility shim and webpack aliasing to transparently redirect its internal react-syntax-highlighter imports to the project's existing prism-react-renderer implementation.
    • This removed the heavyweight react-syntax-highlighter/refractor runtime from the client bundle without modifying Schyma or affecting its functionality.

Performance Improvements Metrics

Before

  • Performance Score: 44–65 across most of the affected routes.
  • Total Blocking Time (TBT): 600 ms
  • Largest Contentful Paint (LCP): 2.3 s
  • Speed Index (SI): 1.8 s
image

After

  • Performance Score: 82–100, with an average Lighthouse score of 96 across the optimized routes.
  • Total Blocking Time (TBT): 50 ms
  • Largest Contentful Paint (LCP): 1.3 s
  • Speed Index (SI): 0.9s
image

Note: The screenshots below were generated using Lighthouse CI on a local production build, providing a consistent performance comparison across all evaluated routes.

image image image

Future improvements

This PR delivers the most significant performance improvement identified during the Lighthouse optimization effort.

  • A few remaining pages may still have optimization opportunities. Some have already reached their practical optimization limit, but any additional improvements that can be achieved will be addressed in follow-up PRs.
image

Related issue

Fixes: #3186

Summary by CodeRabbit

  • New Features
    • Upgraded code block rendering to Prism-based highlighting with consistent theming and improved support for line numbers/selected line highlighting.
    • Added optional bundle analysis via new analyze scripts (server/browser) to inspect build output size.
  • Chores
    • Switched from the previous syntax-highlighter to a lightweight compatibility shim for consistent rendering.
    • Updated dependencies: removed react-syntax-highlighter, added reactflow and cross-env, and added @next/bundle-analyzer.
  • Refactor/Style
    • Applied readability-focused formatting improvements to build tooling.

…m-react-renderer

- Add bundle analyzer setup and documentation
- Create lightweight shim for react-syntax-highlighter
- Migrate CodeBlock to use prism-react-renderer directly
- Configure webpack alias to redirect imports to the shim
- Reduce bundle size by removing unused Refractor language definitions
�
@netlify

netlify Bot commented Jun 26, 2026

Copy link
Copy Markdown

Deploy Preview for asyncapi-website ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 619ce1f
🔍 Latest deploy log https://app.netlify.com/projects/asyncapi-website/deploys/6a520b052bb7020007a5cc2c
😎 Deploy Preview https://deploy-preview-5599--asyncapi-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR replaces code highlighting with prism-react-renderer, adds a compatibility shim, updates Next.js aliasing and bundle analysis wiring, adjusts package scripts and dependencies, reformats tool-building code, and extracts ignore matching logic.

Changes

Prism highlighting and build wiring

Layer / File(s) Summary
CodeBlock Prism render
components/editor/CodeBlock.tsx
CodeBlock normalizes languages and renders Prism tokens with custom theming, manual line numbers, highlighted-line styling, and existing tab/copy behavior.
Compatibility shim
components/shims/react-syntax-highlighter-shim.tsx
A local shim renders Prism-based highlighting, supports line numbers and custom styles, and exports Prism compatibility aliases.
Build wiring and dependencies
next.config.mjs, package.json
Next.js aliases legacy highlighter imports to the shim, conditionally enables bundle analysis, and adds related scripts and dependencies.
Book icon header order
components/icons/Book.tsx
The Book icon module reorders the React import and component JSDoc block.

Tool-building refactor

Layer / File(s) Summary
Tool build orchestration
scripts/build-tools.ts
Existing tool extraction, parsing, combination, validation, and CLI error handling are reformatted into multiline steps.
Tool combination flow
scripts/tools/combine-tools.ts
Tool enrichment, ignore matching, automated/manual filtering, sorting, and JSON/audit output handling are reorganized and reformatted.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CodeBlock
  participant Highlight
  participant CodeLine
  CodeBlock->>Highlight: pass normalized language and code content
  Highlight->>CodeLine: provide tokenized lines and line props
  CodeLine-->>CodeBlock: render styled lines, numbers, and tokens
Loading

Suggested reviewers: derberg, akshatnema, anshgoyalevil, sambhavgupta0705, princerajpoot20, asyncapi-bot-eve, Mayaleeeee

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The performance work is relevant, but the issue also calls for accessibility-label fixes that are not reflected in the changed files. Add the missing accessibility-label updates and verify the Lighthouse workflow covers the required page set.
Out of Scope Changes check ⚠️ Warning package.json adds reactflow, which is unrelated to the syntax-highlighter swap and bundle-analysis work. Move the reactflow addition to a separate PR unless it is required for the performance work.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed It clearly summarizes the main change: replacing react-syntax-highlighter with Prism to reduce bundle size.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@asyncapi-bot

asyncapi-bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

⚡️ Lighthouse report for the changes in this PR:

Category Score
🟠 Performance 50
🟢 Accessibility 98
🟢 Best practices 92
🟢 SEO 100
🔴 PWA 33

Lighthouse ran on https://deploy-preview-5599--asyncapi-website.netlify.app/

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@next.config.mjs`:
- Around line 12-19: The static import of the bundle analyzer in next.config.mjs
can crash production when devDependencies are omitted, so change the config to
load `@next/bundle-analyzer` only when ANALYZE is true. Update the next.config.mjs
export to use an async default function and apply a conditional dynamic import
around the existing withBundleAnalyzer setup, keeping the rest of the Next.js
config unchanged. Ensure the analyzer wrapper is only created in the ANALYZE
path and otherwise returns the plain config.

In `@package.json`:
- Around line 10-12: The analyze:server and analyze:browser scripts in
package.json are misleading because next.config.mjs only checks ANALYZE and
ignores BUNDLE_ANALYZE, so both scripts currently behave the same. Remove the
unused BUNDLE_ANALYZE assignments from those script entries, or consolidate them
into one analyze script if no separate server/browser reports are actually
produced, and keep the script names aligned with the behavior in next.config.mjs
and npm run build.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 79335269-84a6-49c2-b240-20dced03182b

📥 Commits

Reviewing files that changed from the base of the PR and between 63ccbe3 and ce34b8c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • components/editor/CodeBlock.tsx
  • components/shims/react-syntax-highlighter-shim.tsx
  • next.config.mjs
  • package.json

Comment thread next.config.mjs Outdated
Comment thread package.json
@github-actions github-actions Bot added the microgrant Participation in the Microgrant Program label Jun 26, 2026
@aeworxet aeworxet moved this to In Progress in Microgrant Program Jun 26, 2026
…olving this lint error and not performance

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
components/editor/CodeBlock.tsx (1)

173-173: 🎯 Functional Correctness | 🔵 Trivial

Verify Prism language normalization before shipping

CodeBlockProps.language is a generic string, and Highlight receives codeLanguage as any without validation or normalization. The codebase contains Markdown/MDX files using non-Prism language identifiers (e.g., mermaid, asyncapi, generator-cli) that bypass TypeScript checks due to the as any cast.

While prism-react-renderer typically defaults unknown languages to plain text, this leaves no compile-time safety or runtime handling for unsupported aliases. Add a normalization utility to map common aliases to valid Prism identifiers (e.g., ymlyaml, shbash) and implement a fallback to plaintext for unsupported values.

// Example normalization
const normalizeLanguage = (lang?: string): string => {
  const map: Record<string, string> = { yml: 'yaml', sh: 'bash', js: 'javascript', ts: 'typescript' };
  if (!lang) return 'plaintext';
  const normalized = map[lang.toLowerCase()] || lang.toLowerCase();
  // Validate against Prism languages list or fallback to 'plaintext'
  return supportedLanguages.includes(normalized) ? normalized : 'plaintext';
};

Update line 149 to use normalizeLanguage(currentBlock?.language || language) instead of direct usage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/editor/CodeBlock.tsx` at line 173, The CodeBlock highlighting path
uses a raw string cast to any, so unsupported or aliased languages can slip
through without validation. Add a normalization helper in CodeBlock.tsx to map
common aliases like yml to yaml and sh to bash, then verify the result against
Prism-supported languages. Use the normalized value when computing the language
for Highlight and fall back to plaintext for unknown or missing values instead
of passing codeLanguage as any.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/editor/CodeBlock.tsx`:
- Around line 176-177: Fix the Prettier/ESLint formatting violation in the
className template literal inside CodeBlock by reformatting the conditional
expression and wrapping so it matches the project’s Prettier style. Keep the
same logic in CodeBlock, but adjust the multiline template literal formatting
around showLineNumbers, textSizeClassName, and codeClassName so CI passes.

---

Nitpick comments:
In `@components/editor/CodeBlock.tsx`:
- Line 173: The CodeBlock highlighting path uses a raw string cast to any, so
unsupported or aliased languages can slip through without validation. Add a
normalization helper in CodeBlock.tsx to map common aliases like yml to yaml and
sh to bash, then verify the result against Prism-supported languages. Use the
normalized value when computing the language for Highlight and fall back to
plaintext for unknown or missing values instead of passing codeLanguage as any.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5f794c98-fef8-42a6-a598-65adc8575382

📥 Commits

Reviewing files that changed from the base of the PR and between ce34b8c and 00fec0c.

📒 Files selected for processing (3)
  • components/editor/CodeBlock.tsx
  • components/icons/Book.tsx
  • components/shims/react-syntax-highlighter-shim.tsx
✅ Files skipped from review due to trivial changes (1)
  • components/icons/Book.tsx

Comment thread components/editor/CodeBlock.tsx Outdated

@princerajpoot20 princerajpoot20 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patilpratik1905

  • Have you checked Sonar? It reports 9 issues.

  • CodeRabbit also has some suggestions.

  • The pipeline is failing for this PR.

  • Please be transparent about the sources of evidence you're using to validate these performance metrics so that we can re-verify them on our end as well. Currently, it's just an image (your PR evidence) claiming that the performance has increased. Please provide the link/steps so that we can verify the results and analyze them ourselves.

  • Also, did you check the Lighthouse report already attached to this PR? It seems to have been overlooked.

If you compare that report, the performance improvement is only marginal, from 49 to 55.

Reference:

Before:
https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/1782378977701-22363.report.html

Image

Your PR:
https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/1782466864423-24397.report.html

Screenshot 2026-06-27 at 1 01 11 PM

Could you explain the reason for this discrepancy? You mentioned that the performance had improved significantly, but that isn't reflected in the Lighthouse report.

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (7fd26be) to head (d5dc41d).
⚠️ Report is 38 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #5599   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           23        23           
  Lines          931       931           
  Branches       180       179    -1     
=========================================
  Hits           931       931           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
components/shims/react-syntax-highlighter-shim.tsx (1)

7-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Run Prettier to clear the reported formatting errors.

Static analysis flags numerous prettier/prettier violations across this theme object (trailing commas at Lines 7, 12, 16, …, and array reflow at 27-37). Please run the formatter to resolve them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/shims/react-syntax-highlighter-shim.tsx` around lines 7 - 60, Run
Prettier on the theme object in the react syntax highlighter shim, including the
style entries and multiline types array, to normalize trailing commas, spacing,
and array wrapping without changing the theme values.

Source: Linters/SAST tools

next.config.mjs (1)

74-86: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Name the async config function (SonarCloud).

The conditional dynamic import correctly resolves the earlier MODULE_NOT_FOUND concern. As a minor follow-up, SonarCloud flags the anonymous async default export; naming it aids stack traces.

♻️ Optional
-export default async function () {
+export default async function buildNextConfig() {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@next.config.mjs` around lines 74 - 86, Name the anonymous async
default-exported configuration function, using a descriptive identifier such as
nextConfig, while preserving its existing dynamic import and returned
configuration behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/editor/CodeBlock.tsx`:
- Around line 355-385: Run the repository formatting command (npm run prettier
or the equivalent format script) across CodeBlock.tsx and the affected files,
ensuring Prettier fixes trailing commas, JSX quote style, and unnecessarily
split expressions. Verify the dedicated lint job passes afterward.
- Around line 374-376: Update the `output` live region in `CodeBlock` so that
when `showIsCopied` is true it announces a copy-success confirmation such as
“Copied to clipboard” instead of the action label “Copy to clipboard”; keep it
empty when false.
- Around line 39-84: Update SUPPORTED_LANGUAGES to include the bundled Prism
languages swift, kotlin, js-extras, and rust, and replace the invalid css-extr
entry with the correct Prism language identifier. Verify normalizeLanguage now
preserves these supported fence languages instead of falling back to plaintext.

In `@components/shims/react-syntax-highlighter-shim.tsx`:
- Around line 40-59: The syntax highlighting style list contains duplicate
definitions for keyword, tag, and selector, with the later rule overriding
earlier colors. Update the style configuration in the React syntax highlighter
shim to consolidate each token type into one entry, preserving the intended
colors and removing the redundant overlapping definitions.

---

Nitpick comments:
In `@components/shims/react-syntax-highlighter-shim.tsx`:
- Around line 7-60: Run Prettier on the theme object in the react syntax
highlighter shim, including the style entries and multiline types array, to
normalize trailing commas, spacing, and array wrapping without changing the
theme values.

In `@next.config.mjs`:
- Around line 74-86: Name the anonymous async default-exported configuration
function, using a descriptive identifier such as nextConfig, while preserving
its existing dynamic import and returned configuration behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 452451a8-b0d9-4b8e-9849-701302ef21d9

📥 Commits

Reviewing files that changed from the base of the PR and between 749931f and a0a4b58.

📒 Files selected for processing (3)
  • components/editor/CodeBlock.tsx
  • components/shims/react-syntax-highlighter-shim.tsx
  • next.config.mjs

Comment on lines +39 to +84
const SUPPORTED_LANGUAGES = new Set<string>([
'markup',
'bash',
'clike',
'c',
'cpp',
'css',
'javascript',
'jsx',
'coffeescript',
'actionscript',
'css-extr',
'diff',
'git',
'go',
'graphql',
'handlebars',
'json',
'less',
'makefile',
'markdown',
'objectivec',
'ocaml',
'python',
'reason',
'sass',
'scss',
'sql',
'stylus',
'tsx',
'typescript',
'wasm',
'yaml',
'plaintext',
'ruby',
]);

/**
* @description Normalizes a language string to a valid Prism identifier.
*/
function normalizeLanguage(lang?: string): Language {
if (!lang) return 'plaintext' as Language;
const lower = lang.toLowerCase();
const mapped = LANGUAGE_ALIASES[lower] || lower;

return (SUPPORTED_LANGUAGES.has(mapped) ? mapped : 'plaintext') as Language;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

prism-react-renderer 2.4.1 default bundled prism languages list

💡 Result:

In prism-react-renderer version 2.4.1, the default bundled Prism languages are defined in the project's language generation configuration [1][2]. The languages explicitly included in the bundle are: * markup * jsx * tsx * swift * kotlin * objectivec * js-extras * reason * rust * graphql * yaml * go * cpp * markdown * python * json [3][2] Please note that this is a base set of languages, and because PrismJS identifies dependencies between languages, including one language may automatically include others required by it (for example, JSX includes JavaScript) [4]. If you require a language not on this list, you can add it by importing the specific definition from the main prismjs package [1][5].

Citations:


🏁 Script executed:

ast-grep outline components/editor/CodeBlock.tsx --view expanded

Repository: asyncapi/website

Length of output: 1237


🏁 Script executed:

sed -n '1,220p' components/editor/CodeBlock.tsx

Repository: asyncapi/website

Length of output: 5061


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- outline ---'
ast-grep outline components/editor/CodeBlock.tsx --view expanded || true

echo '--- file ---'
sed -n '1,220p' components/editor/CodeBlock.tsx

Repository: asyncapi/website

Length of output: 6173


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect related language aliases and package version.
rg -n "SUPPORTED_LANGUAGES|LANGUAGE_ALIASES|prism-react-renderer" components/editor -S
printf '\n--- package.json ---\n'
sed -n '1,220p' package.json

Repository: asyncapi/website

Length of output: 6847


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- CodeBlock.tsx ---'
sed -n '1,220p' components/editor/CodeBlock.tsx

echo
echo '--- searches ---'
rg -n "css-extr|css-extras|js-extras|swift|kotlin|rust|ruby|plaintext|SUPPORTED_LANGUAGES|LANGUAGE_ALIASES" -S .

Repository: asyncapi/website

Length of output: 20628


🌐 Web query:

prism-react-renderer 2.4.1 css-extras js-extras bundled grammar

💡 Result:

In prism-react-renderer version 2.4.1, the library includes a bundled, modified version of PrismJS that contains a core set of common language syntaxes rather than the full Prism library [1][2]. The specific languages included are not fixed to every available Prism grammar but are a curated, "arbitrary" subset intended to keep the bundle size manageable [2][3]. Regarding "css-extras" and "js-extras," these are not guaranteed to be part of the default bundled set in version 2.4.1 [3]. While the library bundles common languages like javascript, css, markup, and others [3], specialized grammar extensions like css-extras or js-extras often need to be added manually if they are not explicitly included in the default list [1][3]. If a language or a specific grammar extension is missing, you can add it by extending the bundled Prism instance [1][3]. The recommended approach is: 1. Import the Prism instance exported by prism-react-renderer [3][4]. 2. Set it to the global scope (if required by your build system) [1][4]. 3. Import the specific language definition from the prismjs/components/ directory [1][4]. Example: import { Highlight, Prism } from "prism-react-renderer"; (typeof global!== "undefined"? global: window).Prism = Prism; await import("prismjs/components/prism-css-extras"); // Adds the missing grammar [1][4] Note that some languages depend on others (e.g., javascript is often bundled or required by its extras), so ensuring the base language is loaded before adding extras is standard practice [1][5]. You can check the current "out of the box" supported languages by inspecting the library's internal configuration files if you require an exhaustive list for your specific installation [2][6].

Citations:


🌐 Web query:

prism-react-renderer 2.4.1 packages generate-prism-languages index.ts languages list

💡 Result:

In prism-react-renderer version 2.4.1, the supported languages are defined in the packages/generate-prism-languages/index.ts file [1][2]. The library bundles a base set of language definitions, which are processed during build time [1][3]. The explicit top-level languages included in the bundle are [1]: - markup - jsx - tsx - swift - kotlin - objectivec - js-extras - reason - rust - graphql - yaml - go - cpp - markdown - json It is important to note that this list contains the top-level languages only [4]. PrismJS automatically includes any dependencies required by these languages (for example, including jsx also includes the base js grammar) [1][4]. If you need a language not included in this list, you can add support for it by importing the specific language definition from the main prismjs package in your own application code [2][5]. Example usage for adding an unsupported language: import { Highlight, Prism } from "prism-react-renderer"; (typeof global!== "undefined"? global: window).Prism = Prism; await import("prismjs/components/prism-applescript"); // Example for adding applescript [2]

Citations:


Align the Prism allowlist with bundled languages. prism-react-renderer 2.4.1 includes swift, kotlin, js-extras, and rust, but they’re missing here, so those fences fall back to plaintext. css-extr also doesn’t match a Prism language name.

🧰 Tools
🪛 ESLint

[error] 73-73: Delete ,

(prettier/prettier)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/editor/CodeBlock.tsx` around lines 39 - 84, Update
SUPPORTED_LANGUAGES to include the bundled Prism languages swift, kotlin,
js-extras, and rust, and replace the invalid css-extr entry with the correct
Prism language identifier. Verify normalizeLanguage now preserves these
supported fence languages instead of falling back to plaintext.

Comment thread components/editor/CodeBlock.tsx
Comment thread components/editor/CodeBlock.tsx
Comment on lines +40 to +59
{
types: ['atrule', 'keyword', 'attr-name', 'selector'],
style: { color: '#00a4db' },
},
{
types: ['function', 'deleted', 'tag'],
style: { color: '#d73a49' },
},
{
types: ['function-variable'],
style: { color: '#6f42c1' },
},
{
types: ['tag', 'selector', 'keyword'],
style: { color: '#00009f' },
},
{
types: ['property'],
style: { color: '#990055' },
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

prism-react-renderer themeToDict duplicate token types style merge order

💡 Result:

In prism-react-renderer, the themeToDict function processes the theme's styles array into a dictionary that maps token types to their corresponding style objects [1][2][3]. Regarding duplicate token types or overlapping definitions, the merge order is determined by the order in which the definitions appear in the theme's styles array [4]. Specifically, the library iterates through the styles array and applies them sequentially [4]. If multiple definitions in the array target the same token type, or if a token's class list matches multiple definitions, later entries in the array will effectively override or merge into the previous ones [4]. Because the implementation uses sequential application, later definitions have higher precedence [4]. If you are attempting to style tokens with finer granularity (e.g., distinguishing between specific combinations of classes vs. general tokens), the current theme system may not support it directly without explicit definitions for each specific combination, as it does not automatically resolve specificity hierarchies like CSS does [4]. If you find that the default precedence is not achieving the desired styling, you can manage this by ordering your styles array so that the most specific rules appear later, ensuring they override more general rules [4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target file with line numbers
sed -n '1,140p' components/shims/react-syntax-highlighter-shim.tsx | cat -n

# Locate the theme usage and any related comments
rg -n "theme|styles|token|keyword|selector|tag|function-variable|deleted" components/shims/react-syntax-highlighter-shim.tsx

Repository: asyncapi/website

Length of output: 5080


Remove the duplicate token definitions
keyword, tag, and selector are defined twice; the later #00009f rule wins, so the earlier colors never apply. Consolidate each token type to a single entry with the intended color.

🧰 Tools
🪛 ESLint

[error] 42-42: Delete ,

(prettier/prettier)


[error] 46-46: Delete ,

(prettier/prettier)


[error] 50-50: Delete ,

(prettier/prettier)


[error] 54-54: Delete ,

(prettier/prettier)


[error] 58-58: Delete ,

(prettier/prettier)


[error] 59-59: Delete ,

(prettier/prettier)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/shims/react-syntax-highlighter-shim.tsx` around lines 40 - 59, The
syntax highlighting style list contains duplicate definitions for keyword, tag,
and selector, with the later rule overriding earlier colors. Update the style
configuration in the React syntax highlighter shim to consolidate each token
type into one entry, preserving the intended colors and removing the redundant
overlapping definitions.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/build-tools.ts (1)

28-176: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Run Prettier to fix formatting violations before merge.

The multi-line formatting introduced by this PR doesn't match the project's Prettier configuration. ESLint flags trailing commas (Lines 28, 69, 87, 114, 138), expressions that should be collapsed to one line (Lines 31-38, 41-43, 75-78, 90-92, 118-120, 127-129, 142-144, 150-167, 169-176), and missing blank lines (Lines 80-88). The logic itself is unchanged and correct — only the formatting needs adjustment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/build-tools.ts` around lines 28 - 176, Run the project’s Prettier
formatter on the affected build-tools code, especially the functions that call
combineTools and combineAutomatedAndManualTools and the CLI invocation. Apply
its configured trailing-comma, line-wrapping, expression-collapsing, and
blank-line rules without changing behavior.

Source: Linters/SAST tools

🧹 Nitpick comments (2)
scripts/tools/combine-tools.ts (2)

379-408: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate duplicated ignored-output writing.

The two ignoredOutputPath branches differ only in totalIgnored and ignoredTools values. Consolidating them eliminates ~15 lines of duplication and reduces the risk of the two branches drifting apart.

♻️ Proposed refactor
-    if (ignoredOutputPath && ignoredTools.length > 0) {
-      fs.writeFileSync(
-        ignoredOutputPath,
-        JSON.stringify(
-          {
-            description:
-              'Auto-generated audit log of tools ignored during the last combine run.',
-            generatedAt: new Date().toISOString(),
-            totalIgnored: ignoredTools.length,
-            ignoredTools,
-          },
-          null,
-          2,
-        ),
-      );
-    } else if (ignoredOutputPath && ignoredTools.length === 0) {
-      fs.writeFileSync(
-        ignoredOutputPath,
-        JSON.stringify(
-          {
-            description:
-              'Auto-generated audit log of tools ignored during the last combine run.',
-            generatedAt: new Date().toISOString(),
-            totalIgnored: 0,
-            ignoredTools: [],
-          },
-          null,
-          2,
-        ),
-      );
+    if (ignoredOutputPath) {
+      fs.writeFileSync(
+        ignoredOutputPath,
+        JSON.stringify(
+          {
+            description:
+              'Auto-generated audit log of tools ignored during the last combine run.',
+            generatedAt: new Date().toISOString(),
+            totalIgnored: ignoredTools.length,
+            ignoredTools,
+          },
+          null,
+          2,
+        ),
+      );
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tools/combine-tools.ts` around lines 379 - 408, Consolidate the two
ignoredOutputPath branches in the combine-tools flow into one write operation
guarded only by ignoredOutputPath. Build the audit object using
ignoredTools.length and ignoredTools directly so both empty and non-empty cases
share the same description, timestamp, formatting, and output behavior.

105-145: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Unify string and array language handling to reduce cognitive complexity.

The string branch (lines 105–124) and the array branch (lines 126–145) share near-identical search-or-create logic. Normalizing the string case to a single-element array at the top would eliminate the duplication and reduce getFinalTool's cognitive complexity (SonarCloud flags 23, limit is 15).

♻️ Proposed refactor
   // there might be a tool without language
   if (toolObject.filters.language) {
     const languageArray: LanguageColorItem[] = [];
-
-    if (typeof toolObject.filters.language === 'string') {
-      const languageSearch = await languageFuse.search(
-        toolObject.filters.language,
-      );
-
-      if (languageSearch.length) {
-        languageArray.push(languageSearch[0].item);
-      } else {
-        // adds a new language object in the Fuse list as well as in tool object
-        // so that it isn't missed out in the UI.
-        const languageObject = {
-          name: toolObject.filters.language,
-          color: 'bg-[`#57f281`]',
-          borderColor: 'border-[`#37f069`]',
-        };
-
-        languageList.push(languageObject);
-        languageArray.push(languageObject);
-        languageFuse = new Fuse(languageList, options);
-      }
-    } else {
-      for (const language of toolObject.filters.language) {
-        // eslint-disable-next-line no-await-in-loop
-        const languageSearch = await languageFuse.search(language);
-
-        if (languageSearch.length > 0) {
-          languageArray.push(languageSearch[0].item);
-        } else {
-          // adds a new language object in the Fuse list as well as in tool object
-          // so that it isn't missed out in the UI.
-          const languageObject = {
-            name: language,
-            color: 'bg-[`#57f281`]',
-            borderColor: 'border-[`#37f069`]',
-          };
-
-          languageList.push(languageObject);
-          languageArray.push(languageObject);
-          languageFuse = new Fuse(languageList, options);
-        }
-      }
+    const languages = typeof toolObject.filters.language === 'string'
+      ? [toolObject.filters.language]
+      : toolObject.filters.language;
+
+    for (const language of languages) {
+      // eslint-disable-next-line no-await-in-loop
+      const languageSearch = await languageFuse.search(language);
+
+      if (languageSearch.length > 0) {
+        languageArray.push(languageSearch[0].item);
+      } else {
+        // adds a new language object in the Fuse list as well as in tool object
+        // so that it isn't missed out in the UI.
+        const languageObject = {
+          name: language,
+          color: 'bg-[`#57f281`]',
+          borderColor: 'border-[`#37f069`]',
+        };
+
+        languageList.push(languageObject);
+        languageArray.push(languageObject);
+        languageFuse = new Fuse(languageList, options);
+      }
     }
     finalObject.filters.language = languageArray;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/tools/combine-tools.ts` around lines 105 - 145, Refactor the language
handling in getFinalTool by normalizing a string-valued
toolObject.filters.language into a single-element array before iterating.
Replace the separate string and array branches with one loop that performs the
existing Fuse search-or-create logic for each language, preserving
languageArray, languageList, and languageFuse updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/editor/CodeBlock.tsx`:
- Around line 262-285: Update the clipboard handling in the CodeBlock copy
method to catch navigator.clipboard.writeText rejection and fall back to the
existing textarea copy path. Extract the duplicated successful-copy state update
(setShowIsCopied and its timeout) into a reusable local helper, invoking it
after either copy method succeeds while preserving current behavior.

---

Outside diff comments:
In `@scripts/build-tools.ts`:
- Around line 28-176: Run the project’s Prettier formatter on the affected
build-tools code, especially the functions that call combineTools and
combineAutomatedAndManualTools and the CLI invocation. Apply its configured
trailing-comma, line-wrapping, expression-collapsing, and blank-line rules
without changing behavior.

---

Nitpick comments:
In `@scripts/tools/combine-tools.ts`:
- Around line 379-408: Consolidate the two ignoredOutputPath branches in the
combine-tools flow into one write operation guarded only by ignoredOutputPath.
Build the audit object using ignoredTools.length and ignoredTools directly so
both empty and non-empty cases share the same description, timestamp,
formatting, and output behavior.
- Around line 105-145: Refactor the language handling in getFinalTool by
normalizing a string-valued toolObject.filters.language into a single-element
array before iterating. Replace the separate string and array branches with one
loop that performs the existing Fuse search-or-create logic for each language,
preserving languageArray, languageList, and languageFuse updates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ec876f6b-cd63-4c7f-aaf8-1466d0f81ce6

📥 Commits

Reviewing files that changed from the base of the PR and between a0a4b58 and 41b05dd.

📒 Files selected for processing (3)
  • components/editor/CodeBlock.tsx
  • scripts/build-tools.ts
  • scripts/tools/combine-tools.ts

Comment thread components/editor/CodeBlock.tsx
…Cloud top-level await issue"

This reverts commit c136a7e.
@sonarqubecloud

Copy link
Copy Markdown

@patilpratik1905

Copy link
Copy Markdown
Author

Hi @princerajpoot20
Just wanted to give an update on the PR.

I spent quite long time of week investigating the npm run build issues because I wanted to verify the actual performance improvements before pushing further changes. During the build I ran into multiple issues (dependency/platform-related initially, followed by build/type/lint issues), so a significant amount of time went into getting the project building correctly in order to validate the Lighthouse results. Right now I have shifted to wsl and it works fine

From my local testing (Lighthouse CI + Chrome DevTools), the changes show a noticeable improvement, especially in reducing Total Blocking Time (TBT). Desktop metrics improved significantly, while mobile also improved, although not shown by deployed vercel link as much as I'd hoped.

Alongside that, I've been addressing SonarCloud and CodeRabbit feedback continuously. Every time I resolved one issue, another followup Sonar and CodeRabbit issues along with lint/style issue appeared in CI. While fixing those, a few extra files were added in this PR especially the build file which was just part of solving lint issue came in CI

At the moment I'm stuck with a Git issue where the lint fixes are reflected locally, but Git isn't detecting any differences when I try to stage the files. I'm investigating that now.

In the meantime, I'd really appreciate it if you could review the current code changes.

Regarding the Lighthouse improvement concern, I think the smaller gain mainly comes from the mobile Lighthouse score, which is generally much stricter than desktop. I also have two follow-up optimization ideas that I'd prefer to keep as separate PRs:

  1. Local fonts instead of external font loading. I tried this previously and it noticeably improved performance, but it also changed the website's typography. I remember there were concerns about preserving the current UI, so I'll revisit this carefully and see if there's a way to get the performance benefit without affecting the visual appearance.

  2. Further performance optimizations, such as deferring heavy libraries (e.g. Mermaid/charts where applicable), lazy-loading non-critical code, and preloading the LCP image/component where possible to reduce initial page load work.

Do you think these optimizations would be okay as two separate follow-up PRs?

@princerajpoot20 princerajpoot20 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patilpratik1905

Revert all the changes you've made to the tools workflow. The Sonar issue you're seeing will be resolved after that.

You don't need to fix that Sonar finding in the tools workflow ("Prefer top-level await over an async IIFE.").
We intentionally kept the implementation as it is, and the reason is explained here: #5225 (comment). Please take a look.

Since these are unrelated changes, just remove them, and Sonar will no longer report that issue.

Also PTAL #3186 (comment)

cc: @aeworxet

Comment on lines +26 to +55
const LANGUAGE_ALIASES: Record<string, string> = {
yml: 'yaml',
sh: 'bash',
shell: 'bash',
js: 'javascript',
ts: 'typescript',
py: 'python',
rb: 'ruby',
asyncapi: 'yaml',
'generator-cli': 'bash',
mermaid: 'plaintext',
};

const SUPPORTED_LANGUAGES = new Set<string>([
'markup',
'bash',
'clike',
'c',
'cpp',
'css',
'javascript',
'jsx',
'coffeescript',
'actionscript',
'css-extr',
'diff',
'git',
'go',
'graphql',
'handlebars',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the need of these set values? seems like unrelated changes

Comment on lines +77 to +103
function resolveTag(
name: string,
list: LanguageColorItem[],
fuse: Fuse<LanguageColorItem>,
defaultColor: string,
defaultBorder: string,
): { item: LanguageColorItem; fuse: Fuse<LanguageColorItem> } {
const results = fuse.search(name);

if (results.length > 0) {
return { item: results[0].item, fuse };
}

const newItem: LanguageColorItem = {
name,
color: defaultColor,
borderColor: defaultBorder,
};

list.push(newItem);

return { item: newItem, fuse: new Fuse(list, options) };
}

async function resolveLanguageTags(
language: string | string[],
): Promise<{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, what is the need of making changes in combine-tools file? it's a totally different workflow.

Comment thread scripts/build-tools.ts
Comment on lines 28 to +69
@@ -57,18 +66,30 @@ async function buildTools(
toolsPath: string,
tagsPath: string,
ignorePath?: string,
ignoredOutputPath?: string
ignoredOutputPath?: string,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, there's no need to touch these files. They're unrelated to your changes. If you're getting a lint error, first check where it's coming from instead of running the lint command on the entire project. Otherwise, you'll end up making changes across the entire project that are unrelated to your work.

Comment thread package.json
Comment on lines +10 to +12
"analyze": "cross-env NODE_OPTIONS=--max-old-space-size=16384 npm run build-scripts && cross-env NODE_OPTIONS=--max-old-space-size=16384 ANALYZE=true next build",
"analyze:server": "cross-env ANALYZE=true BUNDLE_ANALYZE=server npm run build",
"analyze:browser": "cross-env ANALYZE=true BUNDLE_ANALYZE=browser npm run build",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What purpose do these commands serve? If they're meant to analyze the bundle, do these commands need to be added to the project? If so, who is going to use them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

microgrant Participation in the Microgrant Program waiting-for-author

Projects

Status: In Progress
Status: To Be Triaged

Development

Successfully merging this pull request may close these issues.

4 participants